<?php
    
    class File
    {
        private $path = '';


        public function  __construct( $filePath )
        {
            $this->path = $filePath;
        }

        public function Output()
        {
            if ( is_file($this->path) )
            {
                ob_start();
                header( 'Content-type: ' . File::GetContentType($this->path) );
                @readfile( $this->path );
                ob_end_flush();
            }
        }

        public static function GetContentType( $file )
        {
            $contentType = '';
            if (function_exists('finfo_file'))
            {
                $finfo = finfo_open(FILEINFO_MIME);
                if ($finfo !== false)
                {
                    $contentType = finfo_file($finfo, $file);
                    finfo_close($finfo);
                }
            }
            else if (function_exists('mime_content_type'))
            {
                $contentType = mime_content_type($file);
            }

            if (!$contentType)
            {
                $contentType = File::GetContentTypeByExtension($file);
            }

            return $contentType;
        }

        /**
         * Returns file extension.
         *
         * @param string $file
         * @return string
         */
        public static function GetFileExtension( $file )
        {
            return pathinfo( $file, PATHINFO_EXTENSION );
        }
        
        /**
         * Returns file name.
         * 
         * @param string $file
         * @return string
         */
        public static function GetFileName($file)
        {
        	return pathinfo($file, PATHINFO_FILENAME);
        }
        
        /**
         * Return file name from url
         *
         * @param string $url
         * @return string
         */
        public static function GetFileNameFromUrl( $url )
        {
            return self::GetFileName(parse_url( $url, PHP_URL_PATH ));
        }

        public static function GetFormattedSize( $file )
        {
            $size = filesize($file);

            return self::FormatSize($size);
        }

        public static function FormatSize($size)
        {
            if ($size > 1024*1024)
            {
                return round($size/1048576, 2) . ' MB';
            }
            if ($size > 1024)
            {
                return round($size/1024, 2) .' KB';
            }
            return $size . ' B';
        }
        
        /**
         * Returns a filename with special characters replaced with underscores.
         * Extension is not touched.
         *
         * @param string $filename
         * @return string
         */
        public static function SanitizeFileName($filename)
        {
            $specialChars = array('\\', '/', '`', '"', '\'', ':', '%', '?', '*', '|', '>', '<', '.', '#');

            $name = $filename;
            $extension = '';
            $lastDotPos = mb_strrpos($filename, '.');
            if ($lastDotPos !== false)
            {
                if ($lastDotPos < mb_strlen($filename) - 1)
                {
                    $extension = mb_substr($filename, $lastDotPos);
                    $name = mb_substr($filename, 0, $lastDotPos);
                }
            }

            $result = str_replace($specialChars, '_', $name) . $extension;

            return $result;
        }

        private static function GetContentTypeByExtension( $file )
        {
            $ext = mb_strtolower( File::GetFileExtension($file) );
            
            switch ($ext)
            {
                case 'txt':  return 'text/plain';
                case 'htm':  return 'text/html';
                case 'html': return 'text/html';
                case 'php':  return 'text/html';
                case 'css':  return 'text/css';
                case 'js':   return 'application/javascript';
                case 'json': return 'application/json';
                case 'xml':  return 'application/xml';
                case 'swf':  return 'application/x-shockwave-flash';
                case 'flv':  return 'video/x-flv';

                // images
                case 'png':  return 'image/png';
                case 'jpe':  return 'image/jpeg';
                case 'jpeg': return 'image/jpeg';
                case 'jpg':  return 'image/jpeg';
                case 'gif':  return 'image/gif';
                case 'bmp':  return 'image/bmp';
                case 'ico':  return 'image/vnd.microsoft.icon';
                case 'tiff': return 'image/tiff';
                case 'tif':  return 'image/tiff';
                case 'svg':  return 'image/svg+xml';
                case 'svgz': return 'image/svg+xml';

                // archives
                case 'zip': return 'application/zip';
                case 'rar': return 'application/x-rar-compressed';
                case 'exe': return 'application/x-msdownload';
                case 'msi': return 'application/x-msdownload';
                case 'cab': return 'application/vnd.ms-cab-compressed';

                // audio/video
                case 'mp3': return 'audio/mpeg';
                case 'qt':  return 'video/quicktime';
                case 'mov': return 'video/quicktime';

                // adobe
                case 'pdf': return 'application/pdf';
                case 'psd': return 'image/vnd.adobe.photoshop';
                case 'ai':  return 'application/postscript';
                case 'eps': return 'application/postscript';
                case 'ps':  return 'application/postscript';

                // ms office
                case 'doc': return 'application/msword';
                case 'rtf': return 'application/rtf';
                case 'xls': return 'application/vnd.ms-excel';
                case 'ppt': return 'application/vnd.ms-powerpoint';

                // open office
                case 'odt': return 'application/vnd.oasis.opendocument.text';
                case 'ods': return 'application/vnd.oasis.opendocument.spreadsheet';
            }
            
            return 'application/octet-stream';
        }
    }

?>